//
//  MMWDHPhotoBrowser.m
//  MMWPT
//
//  Created by 高得华 on 2018/12/12.
//  Copyright © 2018年 高得华. All rights reserved.
//

#import "MMWDHPhotoBrowser.h"
#if __has_include(<AFNetworking/AFNetworking.h>)
#import <AFNetworking/AFNetworking.h>
#else
#import "AFNetworking.h"
#endif
#import "GEdwardInfoController.h"
#import "GEdwardJTOAPPInter.h"
#import "LFAssetManager+SaveAlbum.h"
#import "LFVideoEditingController.h"
#import "LFResultObject_property.h"
#import "UIViewController+HUD.h"

#if __has_include("MDHPT/MDHPT-Swift.h")
#import "MDHPT/MDHPT-Swift.h"
#else
#import "MDHPT-Swift.h"
#endif

#import "LFPhotoBrowser.h"
#import "LFAssetManager.h"
#import "HXPhotoPicker.h"
#import "LFPhotoEditingController.h"

#import "HQImageEditViewController.h"

NSString * const kMMWDHPhotoBrowserFileListTempExtension = @".tmp";
NSString * const kMMWDHPhotoBrowserPhotoBrower = @"kMMWDHPhotoBrowserPhotoBrower";
NSString * const kMMWDHPhotoBrowserSaveImageFailureReason = @"图片需要下载完成";
NSString * const kMMWDHPhotoBrowserSaveImageSuccessMessage = @"^_^ 保存成功!!";
NSString * const kMMWDHPhotoBrowserSaveImageFailureMessage = @"/(ㄒoㄒ)/~~ 保存失败!!";

/** 单例 */
const NSMutableDictionary * downloadDicts;


//MARK: 选择 图片 、 视频的属性类
@interface MMWDHPhotoBrowserSelectModel ()
@end
@implementation MMWDHPhotoBrowserSelectModel

- (instancetype)init {
    if (self = [super init]) {
        self.allow    = kMMWDHPhotoBrowserSelectEnumDefault;
        self.maxCount = 1;
        self.preview  = true;
        self.maxVideoDuration = 120;
        self.maxRecordDuration = 15;
    }
    return self;
}

//MARK: - ===== 20190419 改版 ===== -
///图片/视频选择器的管理者
- (HXPhotoManager *)manager
{
    if (!_manager) {
        _manager = [[HXPhotoManager alloc] initWithType:HXPhotoManagerSelectedTypePhoto];
        //视频最大选择数 默认1 - 必填
        _manager.configuration.videoMaxNum = 1;
        ///视频最大选择数 默认1 - 必填
        _manager.configuration.photoMaxNum = 1;
        ///删除临时的照片/视频 -
        _manager.configuration.deleteTemporaryPhoto = false;
        ///是否开启查看LivePhoto功能呢 - 默认 NO
        _manager.configuration.lookLivePhoto = true;
        ///拍摄的 照片/视频 是否保存到系统相册  默认NO
        _manager.configuration.saveSystemAblum = true;
        ///图片和视频是否能够同时选择 默认 NO
        _manager.configuration.selectTogether = false;
        ///照片列表是否按照片日期排序  默认YES
        _manager.configuration.creationDateSort = true;
        //_manager.configuration.supportRotation = NO;
        //_manager.configuration.cameraCellShowPreview = NO;
        
        ///相册列表每行多少个照片 默认4个 iphone 4s / 5  默认3个
        //_manager.configuration.rowCount = 3;
        ///下载iCloud上的资源  默认YES
        _manager.configuration.downloadICloudAsset = true;
        ///是否需要显示日期section  默认YES
        _manager.configuration.showDateSectionHeader = false;
        ///照片列表倒序 默认 NO
        _manager.configuration.reverseDate = false;
        //是否隐藏原图按钮  默认 NO
        _manager.configuration.hideOriginalBtn = false;
        //是否过滤iCloud上的资源 默认NO
        _manager.configuration.filtrationICloudAsset = false;
        ///是否打开相机功能
        _manager.configuration.openCamera = true;
        
        ///导航 等 的颜色
        //_manager.configuration.themeColor = [UIColor colorFFE500];
        _manager.configuration.navigationBar = ^(UINavigationBar *navigationBar, UIViewController *viewController) {
            //[navigationBar setBackgroundImage:[UIImage imageNamed:@"APPCityPlayer_bannerGame"] forBarMetrics:UIBarMetricsDefault];
            //navigationBar.barTintColor = [UIColor redColor];
        };
        //_manager.configuration.sectionHeaderTranslucent = NO;
        //_manager.configuration.navBarBackgroudColor = [UIColor redColor];
        //_manager.configuration.sectionHeaderSuspensionBgColor = [UIColor redColor];
        //_manager.configuration.sectionHeaderSuspensionTitleColor = [UIColor whiteColor];
        //_manager.configuration.statusBarStyle = UIStatusBarStyleLightContent;
        //_manager.configuration.selectedTitleColor = [UIColor redColor];
        
        //_manager.configuration.requestImageAfterFinishingSelection = YES;
        //__weak typeof(self) weakSelf = self;
        _manager.configuration.photoListBottomView = ^(HXPhotoBottomView *bottomView) {
            //bottomView.bgView.barTintColor = weakSelf.bottomViewBgColor;
        };
        _manager.configuration.previewBottomView = ^(HXPhotoPreviewBottomView *bottomView) {
            //bottomView.bgView.barTintColor = weakSelf.bottomViewBgColor;
        };
        _manager.configuration.albumListCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"albumList:%@",collectionView);
        };
        _manager.configuration.photoListCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"photoList:%@",collectionView);
        };
        _manager.configuration.previewCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"preview:%@",collectionView);
        };
        //_manager.configuration.movableCropBox = YES;
        //_manager.configuration.movableCropBoxEditSize = YES;
        //_manager.configuration.movableCropBoxCustomRatio = CGPointMake(1, 1);
        
        //_manager.shouldSelectModel = ^NSString *(HXPhotoModel *model) {
        //// 如果return nil 则会走默认的判断是否达到最大值
        ////return nil;
        //return @"Demo1 116 - 120 行注释掉就能选啦~\(≧▽≦)/~";
        //};
        _edit = [MDHPhotoVideoEditManager manager:_manager];
    }
    return _manager;
}
///编辑者
- (MDHPhotoVideoEditManager *)edit {
    if (!_edit) {
        _edit = [MDHPhotoVideoEditManager manager:self.manager];
    }
    return _edit;
}

@end



@interface MMWDHPhotoBrowser ()
<
LFPhotoBrowserDelegate,
LFPhotoBrowserDownloadDelegate,
HQImageEditViewControllerDelegate
>


//,
//LFPhotoEditingControllerDelegate,
//LFVideoEditingControllerDelegate

/*
 NSMapTable 是在 NSDictionary 之后的一个可变集合模型化的类，它们具有以下区别：
 1. 主要的差别是 NSMapTable 会在集合里的对象被回收的时候删除此对象来保持对键 和/或 值保持“弱引用”；
 2. 当 NSMapTable 添加一个键值对的时候其键或值可以被复制，也可以使用指针标识来进行相等和散列判断；
 3. NSMapTable 可以包含任意指针（其内容不被约束为对象）。
 
 你可以将 NSMapTable 实例配置为对任意指针进行操作，而不仅仅是对象，尽管通常会鼓励使用 C 的 API： void * 指针来操作。 （有关详细信息，请参阅管理映射表）基于对象的 API（例如 setObject：forKey :)将无法在不进行类型转换的情况下对无对象指针操作。
 */
@property (nonatomic, strong) NSMapTable * mapTable;
///展示视图
@property (nonatomic, strong) LFPhotoBrowser *pbVC;

///图片/视频选择器的管理者
@property (strong, nonatomic) HXPhotoManager *manager;
///图片视频的编辑者
@property (strong, nonatomic) MDHPhotoVideoEditManager * editManager;
//@property (strong, nonatomic) HXPhotoModel *beforePhotoModel;
//@property (strong, nonatomic) HXPhotoModel *beforeVideoModel;
//@property (strong, nonatomic) HXDatePhotoToolManager *toolManager;

///裁剪的block 回调
@property (nonatomic, copy) void(^blockCutImage)(UIImage * image);

@end

@implementation MMWDHPhotoBrowser

static MMWDHPhotoBrowser * _instance = nil;

///单例
+ (MMWDHPhotoBrowser *)shared {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:NULL] init] ;
        //不是使用alloc方法，而是调用[[super allocWithZone:NULL] init]
        //已经重载allocWithZone基本的对象分配方法，所以要借用父类（NSObject）的功能来帮助出处理底层内存分配的杂物
    });
    return _instance;
}
+(id)allocWithZone:(struct _NSZone *)zone {
    return [MMWDHPhotoBrowser shared] ;
}
- (id) copyWithZone:(struct _NSZone *)zone {
    return [MMWDHPhotoBrowser shared];
}
- (instancetype)init {
    if (self = [super init]) {
        self.mapTable = [NSMapTable weakToWeakObjectsMapTable];
    }
    return self;
}


//MARK: 选择照片
///选择照片 视频
- (void)selectVideoPhoto:(MMWDHPhotoBrowserSelectModel *)model block:(kBlockMMWDHPhotoBrowserSelect)block {
    UIViewController * topVc = [MDHRouter sharedInstance].navigationControllerStack.topViewController;
    ///返回数据
    void(^blockCancelPvData)(void) = ^{
        DTLog(@"取消了");
        ShowHUDMesHidden(@"取消选择图片/视频~", topVc.view);
        if (block) {
            block([NSArray new]);
        }
    };
    ///清除以前的所选数据
    [self.manager clearSelectedList];
    
    __weak typeof(self) weakSelf = self;
    ///设置图片的配置
    void(^blockSetPhotoPz)(void) = ^{
        weakSelf.manager.configuration.photoMaxNum = model.maxCount;
    };
    ///设置视频的配置
    void(^blockSetVideoPz)(void) = ^{
        weakSelf.manager.configuration.videoMaxNum = model.maxCount;
        ///视频能选择的最大秒数  -  默认 3分钟/180秒
        weakSelf.manager.configuration.videoMaximumSelectDuration = model.maxVideoDuration;
        ///视频能选择的最小秒数  -  默认 0秒 - 不限制
        weakSelf.manager.configuration.videoMinimumSelectDuration = 0;
        ///相机视频录制最大秒数  -  默认60s
        weakSelf.manager.configuration.videoMaximumDuration = model.maxRecordDuration;
    };
    
    ///允许选择的类型
    switch (model.allow) {
        case kMMWDHPhotoBrowserSelectEnumDefault:///图片视频共存
        {
            self.manager.type = HXPhotoManagerSelectedTypePhotoAndVideo;
            blockSetVideoPz();
            blockSetPhotoPz();
        }
            break;
        case kMMWDHPhotoBrowserSelectEnumPhoto:
        {
            self.manager.type = HXPhotoManagerSelectedTypePhoto;
            blockSetPhotoPz();
        }
            break;
        case kMMWDHPhotoBrowserSelectEnumVideo:
        {
            self.manager.type = HXPhotoManagerSelectedTypeVideo;
            blockSetVideoPz();
        }
            break;
        default:
            break;
    }
    
    ///进行转化数据
    void(^blockTransModel)(NSArray<HXPhotoModel *> *allList) = ^(NSArray<HXPhotoModel *> *allList){
        NSMutableArray <LFResultObject *>* datas = [NSMutableArray arrayWithCapacity:1];
        HXPhotoModel * itemModel = nil;
        for (HXPhotoModel * item in allList) {
            if ([item isKindOfClass:[LFResultImage class]]) {
                [datas addObject:(LFResultImage*)item];
                continue;
            }
            UIImage * image = [UIImage new];
            if (item.previewPhoto) {
                image = item.previewPhoto;
            }else if (item.thumbPhoto) {
                image = item.thumbPhoto;
            }else if (item.tempImage) {
                image = item.tempImage;
            }
            if (item.subType == HXPhotoModelMediaSubTypeVideo) {
                itemModel = item;
                break;
            }else{
                LFResultImage * im = [LFResultImage new];
                im.originalImage = image;
                [datas addObject:im];
            }
        }
        if (itemModel) {
            if (itemModel.tempAsset == nil) {
                [[LFAssetManager manager] getVideoResultWithAsset:itemModel.asset completion:^(LFResultVideo *resultVideo) {
                    if (block) {
                        block(@[resultVideo]);
                    }
                }];
            }else{
                LFResultVideo * vi = [LFResultVideo new];
                UIImage * image = [UIImage new];
                if (itemModel.thumbPhoto) {
                    image = itemModel.thumbPhoto;
                }else if (itemModel.tempImage) {
                    image = itemModel.tempImage;
                }
                vi.coverImage = image;
                vi.url = itemModel.fileURL;
                if (block) {
                    block(@[vi]);
                }
            }
        }else {
            if (block) {
                block(datas.copy);
            }
        }
    };
    
    ///进入选择相册的界面
    void(^blockEnterSelectPhoto)(void) = ^{
        [topVc hx_presentSelectPhotoControllerWithManager:self.manager didDone:^(NSArray<HXPhotoModel *> *allList, NSArray<HXPhotoModel *> *photoList, NSArray<HXPhotoModel *> *videoList, BOOL isOriginal, UIViewController *viewController, HXPhotoManager *manager) {
            blockTransModel(allList);
        } cancel:^(UIViewController *viewController, HXPhotoManager *manager) {
            blockCancelPvData();
        }];
    };
    
    if (model.isCamera) {///是否相机显示
        if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            [topVc.view hx_showImageHUDText:@"此设备不支持相机!"];
            return;
        }
        [topVc hx_presentCustomCameraViewControllerWithManager:self.manager done:^(HXPhotoModel *model, HXCustomCameraViewController *viewController) {
            if (model) {
                [weakSelf.manager afterListAddCameraTakePicturesModel:model];
                [[LFAssetManager manager] getPhotoWithAsset:model.asset isOriginal:true completion:^(LFResultImage *resultImage) {
                    blockTransModel(@[(HXPhotoModel *)resultImage]);
                }];
            }else{
                blockCancelPvData();
            }
        } cancel:^(HXCustomCameraViewController *viewController) {
            if (viewController.enterStyle == 2) {
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    blockEnterSelectPhoto();
                });
            }else{
                blockCancelPvData();
            }
        }];
    }else{///显示相册
        blockEnterSelectPhoto();
    }
    
    /*ZLPhotoActionSheet * sheet = [self actionSheetModel:model];
    if (model.preview) {
        [sheet showPreviewAnimated:YES];
    } else {
        [sheet showPhotoLibrary];
    }
    
    [sheet setSelectImageBlock:^(NSArray<UIImage *> * _Nonnull images, NSArray<PHAsset *> * _Nonnull assets, BOOL isOriginal) {
        ///线程组(保证全部执行完毕再返回) 异步 并发队列
        dispatch_group_t group = dispatch_group_create();
        NSMutableArray <LFResultObject*>*result = [NSMutableArray arrayWithCapacity:1];
        ShowHUDMessage(@"正在处理中...", nil);
        
        ///系统的PHAsset 转化成 LFResultObject
        void(^blockAssetTransLFResult)(PHAsset * asset, int i) = ^(PHAsset * asset, int i) {
            if (asset.mediaType == PHAssetMediaTypeVideo) {
                [[LFAssetManager manager] getVideoResultWithAsset:asset completion:^(LFResultVideo *resultVideo) {
                    //DTLog(@"当前是第%d -> %f", i, asset.duration);
                    [result addObject:resultVideo];
                    dispatch_group_leave(group);
                }];
            }else{
                [[LFAssetManager manager] getPhotoWithAsset:asset isOriginal:isOriginal completion:^(LFResultImage *resultImage) {
                    //DTLog(@"当前是第%d -> %f", i, asset.duration);
                    [result addObject:resultImage];
                    dispatch_group_leave(group);
                }];
            }
        };
        
        for (int i = 0; i<assets.count; i++) {
            dispatch_group_enter(group);
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                PHAsset * asset = assets[i];
                blockAssetTransLFResult(asset, i);
            });
        }
        ///线程组的监听通知// 监听my_queue中的任务执行完毕后回到主线程实现任务C
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            if (block) {
                block(result.copy);
            }
            DismissHud(nil);
        });
    }];
    
    sheet.cancleBlock = ^{
        blockCancelPvData();
    };*/
}

/////相册 拍摄方面的工具类
//- (ZLPhotoActionSheet *)actionSheetModel:(MMWDHPhotoBrowserSelectModel *)model {
//    ///当前顶部视图
//    UIViewController * sender = [[AppDelegate sharedAppDelegate] topViewController];
//    
//    if (model.maxCount <= 0) model.maxCount = 1;
//    if (model.maxRecordDuration <= 0) model.maxRecordDuration = 15;
//    if (model.maxVideoDuration <= 0) model.maxVideoDuration = 120;
//    
//    ///只是视频
//    BOOL isV = (model.allow == kMMWDHPhotoBrowserSelectEnumVideo);
//    ///只是照片
//    BOOL isP = (model.allow == kMMWDHPhotoBrowserSelectEnumPhoto);
//    ///全部都OK
//    BOOL isVP = !isV && !isP;
//    ///视频
//    BOOL isVideo = isV || isVP;
//    ///照片
//    BOOL isPhoto = isP || isVP;
//    
//    ZLPhotoActionSheet * sheet = [ZLPhotoActionSheet new];
//    ///参数配置 optional，可直接使用 defaultPhotoConfiguration
//    ///相册框架配置 ZLPhotoConfiguration
//    ///是否升序排列，预览界面不受该参数影响，默认升序 YES
//    sheet.configuration.sortAscending = true;
//    ///是否允许选择照片 默认YES
//    sheet.configuration.allowSelectImage = isPhoto;
//    ///是否允许选择Gif，只是控制是否选择，并不控制是否显示，如果为NO，则不显示gif标识 默认YES
//    sheet.configuration.allowSelectGif = isPhoto;
//    ///是否允许选择视频 默认YES
//    sheet.configuration.allowSelectVideo = isVideo;
//    ///是否允许选择Live Photo，只是控制是否选择，并不控制是否显示，如果为NO，则不显示Live Photo标识 默认NO
//    sheet.configuration.allowSelectLivePhoto = isPhoto;
//    ///是否允许Force Touch功能 默认YES
//    sheet.configuration.allowForceTouch = true;
//    ///是否允许编辑图片，选择一张时候才允许编辑，默认YES
//    sheet.configuration.allowEditImage = true;
//    ///是否允许编辑视频，选择一张时候才允许编辑，默认NO
//    sheet.configuration.allowEditVideo = true;
//    ///是否允许滑动选择 默认 YES
//    sheet.configuration.allowSlideSelect = true;
//    ///是否允许混合选择，即可以同时选择image(image/gif/livephoto)、video类型， 默认YES
//    sheet.configuration.allowMixSelect = true;
//    ///预览界面是否允许拖拽选择 默认 NO
//    sheet.configuration.allowDragSelect = true;
//    //设置相册内部显示拍照按钮 是否允许相册内部拍照 默认YES
//    sheet.configuration.allowTakePhotoInLibrary = true;
//    //设置在内部拍照按钮上实时显示相机俘获画面 是否在相册内部拍照按钮上面实时显示相机俘获的影像 默认 YES
//    sheet.configuration.showCaptureImageOnTakePhotoBtn = true;
//    //设置照片最大预览数
//    sheet.configuration.maxPreviewCount = 20;
//    //设置照片最大选择数
//    sheet.configuration.maxSelectCount = model.maxCount;
//    //设置允许选择的视频最大时长 允许选择视频的最大时长，单位：秒， 默认 120s
//    sheet.configuration.maxVideoDuration = model.maxVideoDuration;
//    ///当该参数为10s时，所选视频时长必须大于等于10s才允许进行编辑
//    sheet.configuration.maxEditVideoTime = 15;
//    //设置照片cell弧度 cell的圆角弧度 默认为0
//    sheet.configuration.cellCornerRadio = 0;
//    //单选模式是否显示选择按钮
//    //actionSheet.configuration.showSelectBtn = YES;
//    //是否在选择图片后直接进入编辑界面
//    sheet.configuration.editAfterSelectThumbnailImage = true;
//    //是否保存编辑后的图片
//    sheet.configuration.saveNewImageAfterEdit = false;
//    //设置编辑比例
//    //actionSheet.configuration.clipRatios = @[GetClipRatio(7, 1)];
//    //是否在已选择照片上显示遮罩层 是否在已选择的图片上方覆盖一层已选中遮罩层，默认 NO
//    sheet.configuration.showSelectedMask = true;
//    //颜色，状态栏样式
//    //sheet.configuration.selectedMaskColor = [UIColor purpleColor];
//    ///原有的导航栏信息
//    UINavigationBar * navigationBar = sender.navigationController.navigationBar;
//    ///导航栏背景颜色
//    UIColor * navBarColor = navigationBar.barTintColor;
//    if (navBarColor == nil) navBarColor = [UIColor whiteColor];
//    ///导航栏标题颜色
//    UIColor * navTitleColor = navigationBar.tintColor;
//    if (navTitleColor == nil) navTitleColor = [UIColor blackColor];
//    sheet.configuration.navBarColor = navBarColor;
//    sheet.configuration.navTitleColor = navTitleColor;
//    //sheet.configuration.bottomBtnsNormalTitleColor = kRGB(80, 160, 100);
//    //sheet.configuration.bottomBtnsDisableBgColor = kRGB(190, 30, 90);
//    //sheet.configuration.bottomViewBgColor = [UIColor blackColor];
//    sheet.configuration.statusBarStyle = sender.preferredStatusBarStyle;
//    //是否允许框架解析图片 回调时候是否允许框架解析图片，默认YES
//    sheet.configuration.shouldAnialysisAsset = true;
//    //框架语言 框架语言，默认 ZLLanguageSystem (跟随系统语言)
//    sheet.configuration.languageType = ZLLanguageSystem;
//    //自定义多语言
//    //actionSheet.configuration.customLanguageKeyValue = @{@"ZLPhotoBrowserCameraText": @"没错，我就是一个相机"};
//    //自定义图片
//    //actionSheet.configuration.customImageNames = @[@"zl_navBack"];
//    
//    //是否使用系统相机
//    //actionSheet.configuration.useSystemCamera = YES;
//    //actionSheet.configuration.sessionPreset = ZLCaptureSessionPreset1920x1080;
//    //actionSheet.configuration.exportVideoType = ZLExportVideoTypeMp4;
//    //actionSheet.configuration.allowRecordVideo = NO;
//    ///最大录制时长，默认 10s，最小为 1s
//    sheet.configuration.maxRecordDuration = model.maxRecordDuration;
//#pragma mark - required
//    //如果调用的方法没有传sender，则该属性必须提前赋值
//    sheet.sender = sender;
//    //记录上次选择的图片
//    sheet.arrSelectedAssets = nil;//self.rememberLastSelSwitch.isOn&&self.maxSelCountTextField.text.integerValue>1 ? self.lastSelectAssets : nil;
//    return sheet;
//}




/**
 展示视图
 
 @param items 视频、图片地址 图片
 @param index 选中的哪个
 */
- (void)showPhoto:(NSArray *)items index:(NSInteger)index {
    NSArray * arr = [self PhotoInfos:items];
    LFPhotoBrowser *pbVC = [[LFPhotoBrowser alloc] initWithImageArray:arr currentIndex:(int)index];
    pbVC.animatedTime = 0.25f;
    pbVC.delegate = self;
    pbVC.downloadDelegate = self;
    pbVC.isNeedPageControl = arr.count > 1;
    pbVC.isWeaker = true;
    pbVC.canPullDown = true;
    self.pbVC = pbVC;
    [self.mapTable setObject:pbVC forKey:kMMWDHPhotoBrowserPhotoBrower];
    [pbVC showPhotoBrowser];
}

//MARK: - LFPhotoBrowserDelegate
- (CGRect)photoBrowserTargetFrameWithIndex:(int)index key:(NSString *)key
{
    return CGRectZero;
}

/** 设置长按列表 */
- (NSArray <LFPhotoSheetAction *>*)photoBrowserLongPressActionItems:(LFPhotoBrowser *)photoBrowser photoInfo:(LFPhotoInfo *)photoInfo object:(id /* UIImage * /NSURL * */)object
{
    return [self ActionPhotoInfo:photoInfo];
}
/** 设置保存按钮（右下角） */
- (void)photoBrowserSavePreview:(LFPhotoBrowser *)photoBrowser photoInfo:(LFPhotoInfo *)photoInfo object:(id /* UIImage * /NSURL * */)object {
    [self buttonSaveImageActionPhotoInfo:photoInfo];
}

- (NSMutableArray <LFPhotoSheetAction *> *)ActionPhotoInfo:(LFPhotoInfo *)photoInfo {
    @weakify(self);
    LFPhotoSheetAction *action1 = [LFPhotoSheetAction actionWithTitle:@"保存图片" style:LFPhotoSheetActionType_Default handler:^(id object) {
        @strongify(self);
        [self buttonSaveImageActionPhotoInfo:photoInfo];
    }];
    
    LFPhotoSheetAction *action2 = [LFPhotoSheetAction actionWithTitle:@"取消" style:LFPhotoSheetActionType_Cancel handler:^(id object) { }];
    
    NSString * urlQRCode = photoInfo.urlQRCode;
    if (urlQRCode && ![urlQRCode containsString:@"weixin"] && ![urlQRCode containsString:@"wechat"]) {
        LFPhotoSheetAction *action3 = [LFPhotoSheetAction actionWithTitle:@"识别图中二维码" style:LFPhotoSheetActionType_Default handler:^(id object) {
            //@strongify(self);
            if ([urlQRCode hasPrefix:@"http"]) {
                [GEdwardJTOAPPInter GESharedSafari:urlQRCode];
                /*if ([urlQRCode containsString:@".wechat.com"]) {
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[@"weixin://scanqrcode" stringByAppendingFormat:@"?%@",urlQRCode]]];
                }
                else if ([urlQRCode containsString:@".qq.com"]) {
                    [GEdwardJTOAPPInter GESharedSafari:urlQRCode];
                }
                else{
                    [GEdwardJTOAPPInter GESharedSafari:urlQRCode];
                    //self.pbVC.dismissBlock = ^{};
                    //[[AppDelegate sharedAppDelegate] pushToH5Vc:photoInfo.urlQRCode title:@"" data:@{@"viewStyle": @"-2"}];
                }*/
            }else{
                AlertViewShowR(urlQRCode, @"粘贴", ^(int index) {
                    if (index == 2) {
                        ///UIPasteboard 这个就是剪贴板
                        [UIPasteboard generalPasteboard].string = urlQRCode;
                        ShowHUDMesHidden(@"粘贴成功~", [MDHRouter sharedInstance].navigationControllerStack.topViewController.view);
                    }
                });
            }
        }];
        return @[action1, action2, action3,].mutableCopy;
    }
    return @[action1, action2, ].mutableCopy;
}


/** 设置更多按钮（右上角） */
- (void)photoBrowserMorePreview:(LFPhotoBrowser *)photoBrowser photoInfo:(LFPhotoInfo *)photoInfo object:(id /* UIImage * /NSURL * */)object {
    [photoBrowser ShowPhotoBrowserRightTopBtn:[self ActionPhotoInfo:photoInfo] object:object];
}

#warning 注释以下方法，视频则为在线播放
//MARK: - LFPhotoBrowserDownloadDelegate
-(void)photoBrowser:(LFPhotoBrowser *)photoBrowser downloadVideoWithPhotoInfo:(LFPhotoInfo *)photoInfo
{
    __weak typeof(self) weakSelf = self;
    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0] stringByAppendingPathComponent:photoInfo.videoUrl.lastPathComponent];
    
    /** 测试下载失败 */
    //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //        photoInfo.downloadFail = YES;
    //        [photoBrowser reloadView:photoInfo];
    //    });
    //
    //
    //    return;
    
    NSString *tempPath = [self getDLTempPathWithSavePath:path];
    signed long long fileSize = 0;
    NSFileManager *fileManager = [NSFileManager new]; // default is not thread safe
    if ([fileManager fileExistsAtPath:tempPath]) {
        NSError *error = nil;
        NSDictionary *fileDict = [fileManager attributesOfItemAtPath:tempPath error:&error];
        if (!error && fileDict) {
            fileSize = [fileDict fileSize];
        }
    }
    
    /** 获取原下载路径续传 */
    [self basicHttpFileDownloadWithUrlString:photoInfo.videoUrl offset:fileSize params:@{} timeout:5.f savePath:path download:^(long long totalBytes, long long totalBytesExpected) {
        
        LFPhotoInfo *b_phtoInfo = [weakSelf.mapTable objectForKey:photoInfo.videoUrl];
        b_phtoInfo.downloadProgress = (float)(totalBytes*1.0/totalBytesExpected);
        
    } success:^{
        
        LFPhotoInfo *b_phtoInfo = [weakSelf.mapTable objectForKey:photoInfo.videoUrl];
        b_phtoInfo.videoPath = path;
        LFPhotoBrowser *pb = [weakSelf.mapTable objectForKey:kMMWDHPhotoBrowserPhotoBrower];
        [pb reloadView:b_phtoInfo];
        
    } failure:^(NSError *error) {
        
        LFPhotoInfo *b_phtoInfo = [weakSelf.mapTable objectForKey:photoInfo.videoUrl];
        /** 更新Model状态 */
        b_phtoInfo.downloadFail = YES;
        LFPhotoBrowser *pb = [weakSelf.mapTable objectForKey:kMMWDHPhotoBrowserPhotoBrower];
        [pb reloadView:b_phtoInfo];
    }];
}


//MARK: - 将相片存入相册, 只回调这个方法
- (void)saveALAssetsLibrary:(UIImage * _Nullable)image {
    if (image == nil) {
        DTLog(@"保存的图片为空----");
        return;
    }
    GEdwardInfoController * info = [GEdwardInfoController sharedInstance];
    NSString * albuName = @"APP相册";
    if (info.CFBundleDisplayName.length > 0) {
        albuName = info.CFBundleDisplayName;
    }
    [[LFAssetManager manager] saveImageToCustomPhotosAlbumWithTitle:albuName images:@[image] complete:^(NSArray<id> *assets, NSError *error) {
        [MDHFileConstant mainAsyncSafe:^{
            if (assets && !error) {
                ShowHUDMesHidden(kMMWDHPhotoBrowserSaveImageSuccessMessage, self.pbVC.view);
            }else{
                ShowHUDMesHidden(kMMWDHPhotoBrowserSaveImageFailureMessage, self.pbVC.view);
            }
        }];
    }];
}

//MARK: ====== 常用函数 ======
- (NSString *)getDLTempPathWithSavePath:(NSString *)path {
    NSString *tempPath = [path stringByAppendingString:kMMWDHPhotoBrowserFileListTempExtension];
    return tempPath;
}

- (BOOL)isExistsDL:(NSString *)url {
    return [downloadDicts objectForKey:url];
}

- (void)cancelDL:(NSString *)url {
    NSURLSessionDataTask *operation = [downloadDicts objectForKey:url];
    [operation cancel];
}

- (void)cancelAllDL {
    [downloadDicts enumerateKeysAndObjectsUsingBlock:^(NSString *  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        [self cancelDL:key];
    }];
}

- (void)basicHttpFileDownloadWithUrlString:(NSString*)aUrlString
                                    offset:(u_int64_t)offset
                                    params:(NSDictionary*)aParams
                                   timeout:(NSTimeInterval)timeout
                                  savePath:(NSString*)aSavePath
                                  download:(GEdwardLFPBCDownloadBlock)aDownload
                                   success:(GEdwardLFPBCSuccessBlock)aSuccess
                                   failure:(GEdwardLFPBCFailureBlock)aFailure {
    
    if (downloadDicts == nil) {
        downloadDicts = [@{} mutableCopy];
    }
    
    if ([self isExistsDL:aUrlString]) return;
    
    NSString *tempPath = [aSavePath stringByAppendingString:kMMWDHPhotoBrowserFileListTempExtension]; // 临时保存路径
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    
    NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"GET" URLString:aUrlString parameters:aParams error:nil];
    request.timeoutInterval = (timeout <= 0 ? 15.f : timeout);
    [request setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData]; // 忽略本地缓存重新下载
    if (offset>0) {
        NSMutableURLRequest *mutableURLRequest = [request mutableCopy];
        [mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];
        request = mutableURLRequest;
    }
    
    manager.securityPolicy.allowInvalidCertificates = YES;
    manager.securityPolicy.validatesDomainName = NO;
    
    NSURLSessionDataTask * task = [manager GET:aUrlString parameters:aParams progress:^(NSProgress * _Nonnull downloadProgress) {
        if (aDownload) {
            aDownload(downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [downloadDicts removeObjectForKey:aUrlString];
        NSError *err;
        NSFileManager *fileManager = [NSFileManager new];
        [fileManager moveItemAtPath:tempPath toPath:aSavePath error:&err];
        
        NSError *error = nil;
        if (error && aFailure)
            aFailure(error);
        else if (aSuccess)
            aSuccess();
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [downloadDicts removeObjectForKey:aUrlString];
        if (aFailure) aFailure(error);
    }];
    
    [downloadDicts setObject:task forKey:aUrlString];
}

///下载网址的 Library
- (void)downloadWithUrl:(NSString *)url {
    LFPhotoInfo * info = [LFPhotoInfo new];
    info.originalImageUrl = url;
    [self buttonSaveImageActionPhotoInfo:info];
}

///MARK: 私有函数
///下载、保存图片
- (void)buttonSaveImageActionPhotoInfo:(LFPhotoInfo *)items {
    if([items.originalImageUrl hasPrefix:@"http"]) { // 图片 -> 如果是网络图片
        NSURL * url = [NSURL URLWithString:items.originalImageUrl];
        SDWebImageDownloader * ymgr = [SDWebImageDownloader sharedDownloader];
        [ymgr downloadImageWithURL:url options:SDWebImageDownloaderUseNSURLCache progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
            if (image) {
                [self saveALAssetsLibrary:image];
            }else{
                ShowHUDMesHidden(kMMWDHPhotoBrowserSaveImageFailureReason, self.pbVC.view);
            }
        }];
    }else{ // 如果是本地图片
        [self saveALAssetsLibrary:items.originalImage];
    }
}

///将传入的数据进行转化
- (NSArray <LFPhotoInfo *> *)PhotoInfos:(NSArray *) infos {
    NSMutableArray *items = [NSMutableArray arrayWithCapacity:infos.count];
    int count = 0, max = 2;
    for (id item in infos) {
        if ([item isKindOfClass:[UIImage class]]) {
            LFPhotoInfo *photo = [LFPhotoInfo photoInfoWithType:PhotoType_image key:nil];
            photo.originalImage = item;
            [items addObject:photo];
            continue;
        }
        if ([item isKindOfClass:[NSString class]]) {
            NSString * url = (NSString *)item;
            if ([url hasSuffix:@".mp4"]) {
                LFPhotoInfo *photo = [LFPhotoInfo photoInfoWithType:PhotoType_video key:nil];
                if (count++ < max) {
                    photo.isNeedSlider = YES;
                }
                photo.isAutoPlay = YES;
                photo.videoPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0] stringByAppendingPathComponent:url.lastPathComponent];
                photo.videoUrl = url;
                photo.isLoading = [self isExistsDL:url];
                [items addObject:photo];
                
                [self.mapTable setObject:photo forKey:url];
            } else {
                LFPhotoInfo *photo = [LFPhotoInfo photoInfoWithType:PhotoType_image key:nil];
                photo.originalImageUrl = url;
                [items addObject:photo];
                /** 图片是内置SD下载，没有必要记录数据源 */
                //[self.mapTable setObject:photo forKey:url];
            }
        }else{
            [items addObject:item];
        }
    }
    return items.copy;
}



//MARK: - ===== 20190419 改版 ===== -
///图片/视频选择器的管理者
- (HXPhotoManager *)manager
{
    if (!_manager) {
        _manager = [[HXPhotoManager alloc] initWithType:HXPhotoManagerSelectedTypePhoto];
        //视频最大选择数 默认1 - 必填
        _manager.configuration.videoMaxNum = 1;
        ///视频最大选择数 默认1 - 必填
        _manager.configuration.photoMaxNum = 1;
        ///删除临时的照片/视频 -
        _manager.configuration.deleteTemporaryPhoto = NO;
        ///是否开启查看LivePhoto功能呢 - 默认 NO
        _manager.configuration.lookLivePhoto = YES;
        ///拍摄的 照片/视频 是否保存到系统相册  默认NO
        _manager.configuration.saveSystemAblum = YES;
        ///图片和视频是否能够同时选择 默认 NO
        _manager.configuration.selectTogether = false;
        ///照片列表是否按照片日期排序  默认YES
        _manager.configuration.creationDateSort = YES;
        //_manager.configuration.supportRotation = NO;
        //_manager.configuration.cameraCellShowPreview = NO;
        
        ///相册列表每行多少个照片 默认4个 iphone 4s / 5  默认3个
        //_manager.configuration.rowCount = 3;
        ///下载iCloud上的资源  默认YES
        _manager.configuration.downloadICloudAsset = true;
        ///是否需要显示日期section  默认YES
        _manager.configuration.showDateSectionHeader = false;
        ///照片列表倒序 默认 NO
        _manager.configuration.reverseDate = false;
        //是否隐藏原图按钮  默认 NO
        _manager.configuration.hideOriginalBtn = false;
        //是否过滤iCloud上的资源 默认NO
        _manager.configuration.filtrationICloudAsset = false;
        ///是否打开相机功能
        _manager.configuration.openCamera = true;
        
        ///导航 等 的颜色
        //_manager.configuration.themeColor = [UIColor colorFFE500];
        _manager.configuration.navigationBar = ^(UINavigationBar *navigationBar, UIViewController *viewController) {
            //[navigationBar setBackgroundImage:[UIImage imageNamed:@"APPCityPlayer_bannerGame"] forBarMetrics:UIBarMetricsDefault];
            //navigationBar.barTintColor = [UIColor redColor];
        };
        //_manager.configuration.sectionHeaderTranslucent = NO;
        //_manager.configuration.navBarBackgroudColor = [UIColor redColor];
        //_manager.configuration.sectionHeaderSuspensionBgColor = [UIColor redColor];
        //_manager.configuration.sectionHeaderSuspensionTitleColor = [UIColor whiteColor];
        //_manager.configuration.statusBarStyle = UIStatusBarStyleLightContent;
        //_manager.configuration.selectedTitleColor = [UIColor redColor];
        
        //_manager.configuration.requestImageAfterFinishingSelection = YES;
        //__weak typeof(self) weakSelf = self;
        _manager.configuration.photoListBottomView = ^(HXPhotoBottomView *bottomView) {
            //bottomView.bgView.barTintColor = weakSelf.bottomViewBgColor;
        };
        _manager.configuration.previewBottomView = ^(HXPhotoPreviewBottomView *bottomView) {
            //bottomView.bgView.barTintColor = weakSelf.bottomViewBgColor;
        };
        _manager.configuration.albumListCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"albumList:%@",collectionView);
        };
        _manager.configuration.photoListCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"photoList:%@",collectionView);
        };
        _manager.configuration.previewCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"preview:%@",collectionView);
        };
        //_manager.configuration.movableCropBox = YES;
        //_manager.configuration.movableCropBoxEditSize = YES;
        //_manager.configuration.movableCropBoxCustomRatio = CGPointMake(1, 1);
        
        //_manager.shouldSelectModel = ^NSString *(HXPhotoModel *model) {
        //// 如果return nil 则会走默认的判断是否达到最大值
        ////return nil;
        //return @"Demo1 116 - 120 行注释掉就能选啦~\(≧▽≦)/~";
        //};
        self.editManager = [MDHPhotoVideoEditManager manager:_manager];
    }
    return _manager;
}


- (void)showBrowser:(MMWDHPhotoBrowserSelectModel *)model block:(void(^)(NSArray <HXPhotoModel *>*))block {
    if (model == nil) {
        return;
    }
    
    UIViewController * topVc = [MDHRouter sharedInstance].navigationControllerStack.topViewController;
    ///返回数据
    void(^blockCancelPvData)(void) = ^{
        DTLog(@"取消了");
        //ShowHUDMesHidden(@"取消选择图片/视频~", topVc.view);
        if (block) {
            block([NSArray new]);
        }
    };
    HXPhotoManager * manager_ = model.manager;
    
    //__weak typeof(self) weakSelf = self;
    ///设置图片的配置
    void(^blockSetPhotoPz)(void) = ^{
        manager_.configuration.photoMaxNum = model.maxCount;
    };
    ///设置视频的配置
    void(^blockSetVideoPz)(void) = ^{
        manager_.configuration.videoMaxNum = model.maxCount;
        ///视频能选择的最大秒数  -  默认 3分钟/180秒
        manager_.configuration.videoMaximumSelectDuration = model.maxVideoDuration;
        ///视频能选择的最小秒数  -  默认 0秒 - 不限制
        manager_.configuration.videoMinimumSelectDuration = 0;
        ///相机视频录制最大秒数  -  默认60s
        manager_.configuration.videoMaximumDuration = model.maxRecordDuration;
    };
    
    ///允许选择的类型
    switch (model.allow) {
        case kMMWDHPhotoBrowserSelectEnumDefault:///图片视频共存
        {
            manager_.type = HXPhotoManagerSelectedTypePhotoAndVideo;
            blockSetVideoPz();
            blockSetPhotoPz();
        }
            break;
        case kMMWDHPhotoBrowserSelectEnumPhoto:
        {
            manager_.type = HXPhotoManagerSelectedTypePhoto;
            blockSetPhotoPz();
        }
            break;
        case kMMWDHPhotoBrowserSelectEnumVideo:
        {
            manager_.type = HXPhotoManagerSelectedTypeVideo;
            blockSetVideoPz();
        }
            break;
        default:
            break;
    }
   
    ///进行转化数据
    void(^blockTransModel)(NSArray<HXPhotoModel *> *allList) = ^(NSArray<HXPhotoModel *> *allList){
        //if (model.isAvatar) {
        //    HXPhotoEditViewController *vc = [[HXPhotoEditViewController alloc] init];
        //    vc.isInside = YES;
        //    vc.model = allList.firstObject;
        //    vc.delegate = self;
        //    vc.manager = manager_;
        //    [topVc presentViewController:vc animated:YES completion:nil];
        //}
        for (HXPhotoModel * item in allList) {
            UIImage * image = [UIImage new];
            if (item.previewPhoto) {
                image = item.previewPhoto;
            }else if (item.thumbPhoto) {
                image = item.thumbPhoto;
            }else if (item.tempImage) {
                image = item.tempImage;
            }
            item.previewPhoto = image;
        }
        if (block) {
            block(allList);
        }
    };
    
    ///进入选择相册的界面
    void(^blockEnterSelectPhoto)(void) = ^{
        [topVc hx_presentSelectPhotoControllerWithManager:manager_ didDone:^(NSArray<HXPhotoModel *> *allList, NSArray<HXPhotoModel *> *photoList, NSArray<HXPhotoModel *> *videoList, BOOL isOriginal, UIViewController *viewController, HXPhotoManager *manager) {
            blockTransModel(allList);
        } cancel:^(UIViewController *viewController, HXPhotoManager *manager) {
            blockCancelPvData();
        }];
    };
    
    if (model.isCamera) {///是否相机显示
        if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            [topVc.view hx_showImageHUDText:@"此设备不支持相机!"];
            return;
        }
        [topVc hx_presentCustomCameraViewControllerWithManager:manager_ done:^(HXPhotoModel *model, HXCustomCameraViewController *viewController) {
            if (model) {
                [manager_ afterListAddCameraTakePicturesModel:model];
                [[LFAssetManager manager] getPhotoWithAsset:model.asset isOriginal:true completion:^(LFResultImage *resultImage) {
                    HXPhotoModel * model = [HXPhotoModel new];
                    model.previewPhoto = resultImage.originalImage;
                    blockTransModel(@[model]);
                }];
            }else{
                blockCancelPvData();
            }
        } cancel:^(HXCustomCameraViewController *viewController) {
            if (viewController.enterStyle == 2) {
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    blockEnterSelectPhoto();
                });
            }else{
                blockCancelPvData();
            }
        }];
    }else{///显示相册
        blockEnterSelectPhoto();
    }
}



///对单张图片进行剪切
- (void)cutIntoPhoto:(UIImage *)image block:(void(^)(UIImage *))block {
    if (image == nil || CGSizeEqualToSize(image.size, CGSizeZero)) {
        return;
    }
    self.blockCutImage = block;
    
    HQImageEditViewController * vc = [HQImageEditViewController new];
    vc.originImage = image;
    vc.delegate = self;
    vc.maskViewAnimation = true;
    vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[MDHRouter sharedInstance].navigationControllerStack.topViewController presentViewController:vc animated:true completion:nil];
    });
}


//MARK: - ===== HQImageEditViewControllerDelegate
///完成
- (void)editController:(HQImageEditViewController *)vc finishiEditShotImage:(UIImage *)image originSizeImage:(UIImage *)originSizeImage {
    if (self.blockCutImage) {
        self.blockCutImage(image);
    }
    self.blockCutImage = nil;
    [vc dismissViewControllerAnimated:true completion:nil];
    //[vc.navigationController popViewControllerAnimated:true];
}
- (void)editControllerDidClickCancel:(HQImageEditViewController *)vc {
    self.blockCutImage = nil;
    [vc dismissViewControllerAnimated:true completion:nil];
    //[vc.navigationController popViewControllerAnimated:true];
}

@end




/// - ==== 图片 视频的编辑管理者
@interface MDHPhotoVideoEditManager ()
<
LFPhotoBrowserDelegate,
LFPhotoBrowserDownloadDelegate,
LFPhotoEditingControllerDelegate,
LFVideoEditingControllerDelegate
>

///相册的管理者
@property (nonatomic, strong, readwrite) HXPhotoManager * manager;
@property (strong, nonatomic) HXPhotoModel *beforePhotoModel;
@property (strong, nonatomic) HXPhotoModel *beforeVideoModel;
@property (strong, nonatomic) HXDatePhotoToolManager *toolManager;

@end

@implementation MDHPhotoVideoEditManager

///初始化数据
+ (MDHPhotoVideoEditManager *)manager:(HXPhotoManager *)manager {
    return [[MDHPhotoVideoEditManager alloc] initWithManager:manager];
}

- (instancetype)initWithManager:(HXPhotoManager *)ma {
    self = [super init];
    if (self) {
        self.manager = ma;
        ///是否可以编辑 及 使用第三方的框架 进行替换 编辑界面
        ma.configuration.photoCanEdit = YES;
        ma.configuration.videoCanEdit = YES;
        ma.configuration.replacePhotoEditViewController = YES;
        ma.configuration.replaceVideoEditViewController = YES;
        
        __weak typeof(self) weakSelf = self;
        //@weakify(self);
        ma.configuration.shouldUseEditAsset = ^(UIViewController *viewController, BOOL isOutside, HXPhotoManager *manager, HXPhotoModel *beforeModel) {
            MDHPhotoVideoEditManager * strongSelf = weakSelf;
            if (strongSelf == nil) {
                strongSelf = self;
            }
            //@strongify(self);
            if (beforeModel.subType == HXPhotoModelMediaSubTypePhoto) {
                strongSelf.beforePhotoModel = beforeModel;
                if (beforeModel.type == HXPhotoModelMediaTypeCameraPhoto) {
                    LFPhotoEditingController *lfPhotoEditVC = [[LFPhotoEditingController alloc] init];
                    lfPhotoEditVC.oKButtonTitleColorNormal = manager.configuration.themeColor;
                    lfPhotoEditVC.cancelButtonTitleColorNormal = manager.configuration.themeColor;
                    
                    lfPhotoEditVC.delegate = strongSelf;
                    if ([beforeModel.tempAsset isKindOfClass:[LFPhotoEdit class]]) {
                        lfPhotoEditVC.photoEdit = beforeModel.tempAsset;
                    }else {
                        lfPhotoEditVC.editImage = beforeModel.previewPhoto;
                    }
                    HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfPhotoEditVC];
                    nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                    [viewController presentViewController:nav animated:true completion:nil];
                }else {
                    [viewController.view hx_showLoadingHUDText:nil];
                    [beforeModel requestImageDataStartRequestICloud:nil progressHandler:nil success:^(NSData *imageData, UIImageOrientation orientation, HXPhotoModel *model, NSDictionary *info) {
                        [viewController.view hx_handleLoading];
                        UIImage *image = [UIImage imageWithData:imageData];
                        if (image.imageOrientation != UIImageOrientationUp) {
                            image = [image hx_normalizedImage];
                        }
                        LFPhotoEditingController *lfPhotoEditVC = [[LFPhotoEditingController alloc] init];
                        lfPhotoEditVC.oKButtonTitleColorNormal = manager.configuration.themeColor;
                        lfPhotoEditVC.cancelButtonTitleColorNormal = manager.configuration.themeColor;
                        
                        lfPhotoEditVC.delegate = strongSelf;
                        if ([beforeModel.tempAsset isKindOfClass:[LFPhotoEdit class]]) {
                            lfPhotoEditVC.photoEdit = beforeModel.tempAsset;
                        }else {
                            lfPhotoEditVC.editImage = image;
                        }
                        HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfPhotoEditVC];
                        nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                        [viewController presentViewController:nav animated:true completion:nil];
                    } failed:^(NSDictionary *info, HXPhotoModel *model) {
                        [viewController.view hx_handleLoading];
                        [viewController.view hx_showImageHUDText:@"资源获取失败!"];
                    }];
                }
            }else {
                strongSelf.beforeVideoModel = beforeModel;
                if (beforeModel.type == HXPhotoModelMediaTypeCameraVideo) {
                    LFVideoEditingController *lfVideoEditVC = [[LFVideoEditingController alloc] init];
                    lfVideoEditVC.delegate = strongSelf;
                    lfVideoEditVC.minClippingDuration = 3.f;
                    if ([beforeModel.tempAsset isKindOfClass:[LFVideoEdit class]]) {
                        lfVideoEditVC.videoEdit = beforeModel.tempAsset;
                    } else {
                        [lfVideoEditVC setVideoURL:beforeModel.videoURL placeholderImage:beforeModel.tempImage];
                    }
                    HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfVideoEditVC];
                    nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                    [viewController presentViewController:nav animated:true completion:nil];
                }else {
                    [viewController.view hx_showLoadingHUDText:nil];
                    [beforeModel requestAVAssetStartRequestICloud:nil progressHandler:nil success:^(AVAsset *avAsset, AVAudioMix *audioMix, HXPhotoModel *model, NSDictionary *info) {
                        
                        [viewController.view hx_handleLoading];
                        if ([avAsset isKindOfClass:[AVURLAsset class]]) {
                            NSURL *video = [(AVURLAsset *)avAsset URL];
                            
                            LFVideoEditingController *lfVideoEditVC = [[LFVideoEditingController alloc] init];
                            lfVideoEditVC.delegate = strongSelf;
                            lfVideoEditVC.minClippingDuration = 5.f;
                            if ([beforeModel.tempAsset isKindOfClass:[LFVideoEdit class]]) {
                                lfVideoEditVC.videoEdit = beforeModel.tempAsset;
                            } else {
                                [lfVideoEditVC setVideoURL:video placeholderImage:[UIImage hx_thumbnailImageForVideo:video atTime:0.1f]];
                            }
                            HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfVideoEditVC];
                            nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                            [viewController presentViewController:nav animated:true completion:nil];
                        }else {
                            [strongSelf.toolManager writeSelectModelListToTempPathWithList:@[beforeModel] requestType:1 success:^(NSArray<NSURL *> *allURL, NSArray<NSURL *> *photoURL, NSArray<NSURL *> *videoURL) {
                                [viewController.view hx_handleLoading];
                                NSURL *video = videoURL.firstObject;
                                
                                LFVideoEditingController *lfVideoEditVC = [[LFVideoEditingController alloc] init];
                                lfVideoEditVC.delegate = strongSelf;
                                lfVideoEditVC.minClippingDuration = 5.f;
                                if ([beforeModel.tempAsset isKindOfClass:[LFVideoEdit class]]) {
                                    lfVideoEditVC.videoEdit = beforeModel.tempAsset;
                                } else {
                                    [lfVideoEditVC setVideoURL:video placeholderImage:[UIImage hx_thumbnailImageForVideo:video atTime:0.1f]];
                                }
                                HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfVideoEditVC];
                                nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                                [viewController presentViewController:nav animated:true completion:nil];
                            } failed:^{
                                [viewController.view hx_handleLoading];
                                [viewController.view hx_showImageHUDText:@"资源获取失败!"];
                            }];
                        }
                    } failed:^(NSDictionary *info, HXPhotoModel *model) {
                        [viewController.view hx_handleLoading];
                        [viewController.view hx_showImageHUDText:@"资源获取失败!"];
                    }];
                }
            }
        };
    }
    return self;
}

- (void)lf_PhotoEditingController:(LFPhotoEditingController *)photoEditingVC didFinishPhotoEdit:(LFPhotoEdit *)photoEdit {
    //[photoEditingVC.navigationController setNavigationBarHidden:NO];
    
    HXPhotoModel *model = [HXPhotoModel photoModelWithImage:photoEdit.editPreviewImage];
    model.tempAsset = photoEdit;
    if (photoEditingVC.navigationController.viewControllers.count > 1) {
        [photoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [photoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
    
    self.manager.configuration.usePhotoEditComplete(self.beforePhotoModel, model);
}

- (void)lf_PhotoEditingController:(LFPhotoEditingController *)photoEditingVC didCancelPhotoEdit:(LFPhotoEdit *)photoEdit {
    //[photoEditingVC.navigationController setNavigationBarHidden:NO];
    
    if (photoEditingVC.navigationController.viewControllers.count > 1) {
        [photoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [photoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
}

- (void)lf_VideoEditingController:(LFVideoEditingController *)videoEditingVC didCancelPhotoEdit:(LFVideoEdit *)videoEdit {
    //[videoEditingVC.navigationController setNavigationBarHidden:NO];
    
    if (videoEditingVC.navigationController.viewControllers.count > 1) {
        [videoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [videoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
}
- (void)lf_VideoEditingController:(LFVideoEditingController *)videoEditingVC didFinishPhotoEdit:(LFVideoEdit *)videoEdit {
    //[videoEditingVC.navigationController setNavigationBarHidden:NO];
    
    HXPhotoModel *model = [HXPhotoModel photoModelWithVideoURL:videoEdit.editFinalURL];
    model.tempAsset = videoEdit;
    
    if (videoEditingVC.navigationController.viewControllers.count > 1) {
        [videoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [videoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
    
    self.manager.configuration.useVideoEditComplete(self.beforeVideoModel, model);
}

@end

